package com.ys.service.finance.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ys.dto.AddDto;
import com.ys.entity.finance.*;
import com.ys.entity.flow.YspModel;
import com.ys.entity.hr.ThrOperateCompanyApply;
import com.ys.entity.sys.TsUserChange;
import com.ys.entity.sys.YsCol;
import com.ys.entity.sys.YsMenu;
import com.ys.entity.sys.YsProcInst;
import com.ys.enume.base.TransactionTypeEnum;
import com.ys.enume.finance.TcwOperateCompanyPrepaymentFlowEnum;
import com.ys.enume.flow.FlowEnum;
import com.ys.enume.flow.YsProcInstEnum;
import com.ys.mapper.finance.*;
import com.ys.mapper.hr.HrMapper;
import com.ys.mapper.hr.ThrOperateCompanyApplyMapper;
import com.ys.service.business.TcwAccountDetailedForCompanyService;
import com.ys.service.finance.TcwOperateCompanyPrepaymentService;
import com.ys.service.finance.TcwWanliPrepaymentRecordedService;
import com.ys.service.flow.YspTaskService;
import com.ys.util.CheckUtil;
import com.ys.util.DateUtil;
import com.ys.util.shiro.ShiroUtils;
import com.ys.vo.Flow;
import com.ys.vo.R;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 万里汇预付款入账单
 */
@Service("tcwWanliPrepaymentRecordedService")
public class TcwWanliPrepaymentRecordedServiceImpl implements TcwWanliPrepaymentRecordedService {
	private static final Logger logger = LoggerFactory.getLogger(TcwWanliPrepaymentRecordedServiceImpl.class);

	@Autowired
	private TcwWanliPrepaymentRecordedMapper tcwWanliPrepaymentRecordedMapper;

	@Autowired
	private TcwWanliPrepaymentRecordedItemMapper tcwWanliPrepaymentRecordedItemMapper;

	@Autowired
	private YspTaskService yspTaskService;

	@Autowired
	private CheckUtil checkUtil;

	@Autowired
	private FinanceMapper financeMapper;

	@Autowired
	private TcwWanliPrepaymentPoolingMapper tcwWanliPrepaymentPoolingMapper;

	@Autowired
	private TcwAccountDetailedForCompanyService tcwAccountDetailedForCompanyService;

	@Autowired
	private ThrOperateCompanyApplyMapper thrOperateCompanyApplyMapper;

	@Autowired
	private HrMapper hrMapper;

	@Autowired
	private TcwOperateCompanyPrepaymentService tcwOperateCompanyPrepaymentService;
	/**
	 * 新增
	 */
	@Override
	public R add(Map<String, Object> params, Long menuId) throws Exception{
		logger.info("新增传参:"+params);
		//参数验证
		String errorBack = checkParams(params, menuId);
		if(errorBack!=null && !"".equals(errorBack)){
			return R.error(errorBack);
		}
		TcwWanliPrepaymentRecorded entity = JSON.parseObject(JSON.toJSONString(params), TcwWanliPrepaymentRecorded.class);
		entity.setStatus(1);//状态
		entity.setEffectStock(0);//审批状态
		//获取制单人信息
		TsUserChange tsUserChange = new TsUserChange().setUserId(ShiroUtils.getUserId()).setOrderby("A.CreateTime DESC").queryFirst();
		if(tsUserChange!=null){
			entity.setCreateChangeId(tsUserChange.getId());//制单人变更信息
		}else {
			return R.error("未查询到制单人信息！");
		}
		//获取汇率信息
		//entity = getExchangeRate(entity);
		//保存列表信息
		R saveItemRes = saveItem(params,entity);
		if(saveItemRes.getCode()==1){
			return saveItemRes;
		}

		//计算主表信息
		entity = countMsg(entity);
		//新增
		tcwWanliPrepaymentRecordedMapper.insert(entity);

		YsMenu ysMenu = new YsMenu().setId(menuId).queryFirst();
		if (ysMenu.getFlowModelId().longValue() != 0L) {
			YspModel yspModel = new YspModel().setId(ysMenu.getFlowModelId()).queryFirst();
			String codeModel = yspModel.getCode();
			String createUserId = ShiroUtils.getUserId();
			yspTaskService.init(codeModel, entity.getBid(), createUserId);
		}
		//return R.ok(EditDto.closeAndReload());
		return R.ok(AddDto.gotoEdit("/web/finance/tcwWanliPrepaymentRecorded/toEdit?bid=" + entity.getBid()));
	}


	/**
	 * 修改
	 */
	@Override
	public R update(Map<String, Object> params, Long menuId) throws Exception{
		logger.info("修改传参:"+params);
		//参数验证
		String errorBack = checkParams(params, menuId);
		if(errorBack!=null && !"".equals(errorBack)){
			return R.error(errorBack);
		}
		TcwWanliPrepaymentRecorded entity = JSON.parseObject(JSON.toJSONString(params), TcwWanliPrepaymentRecorded.class);
		//获取汇率信息
		//entity = getExchangeRate(entity);
		// 验证状态
		YsProcInst ysProcInst = new YsProcInst().setBid(entity.getBid()).queryFirst();
		if (ysProcInst == null) {
			return R.error("审批数据不存在，无法编辑");
		} else if (ysProcInst.getStateFlow() != YsProcInstEnum.StateFlow.INIT.value) {
			return R.error("已流转，无法编辑");
		}

		//保存列表信息
		R saveItemRes = saveItem(params,entity);
		if(saveItemRes.getCode()==1){
			return saveItemRes;
		}

		//计算主表信息
		entity = countMsg(entity);
		tcwWanliPrepaymentRecordedMapper.update(entity);
		return R.ok();
	}


	/**
	 * 获取汇率
	 */
	@Override
	public TcwWanliPrepaymentRecorded getExchangeRate(TcwWanliPrepaymentRecorded entity) throws Exception{

		TcwWanliReconciliation tcwWanliReconciliation = new TcwWanliReconciliation().setBid(entity.getReconciliationBid()).queryFirst();
		//获取币种对应汇率
		BigDecimal exchangeRateByGbp = BigDecimal.ZERO;//GBP计算汇率
		BigDecimal exchangeRateByUsd = BigDecimal.ZERO;//USD计算汇率
		BigDecimal exchangeRateByEur = BigDecimal.ZERO;//EUR计算汇率

		if(tcwWanliReconciliation!=null){
			String reconciliationDayEnd = tcwWanliReconciliation.getReconciliationDayEnd();
			String exchangeRateDay = DateUtil.getYYYY_MM_DD(DateUtil.addDays(reconciliationDayEnd, 1));//汇率获取的日期
			entity.setExchangeRateDay(exchangeRateDay);


			//获取万里汇CNY计算汇率表
			List<TcwWanliExchangeRate> exchangeRateList = new TcwWanliExchangeRate()
					.setDepositPlatformCode(entity.getDepositPlatformCode())
					.where("A.RefreshTime BETWEEN \'"+exchangeRateDay + " 00:00:00" + "\' AND  \'"+ exchangeRateDay + " 23:59:59" + "\'")
					.setOrderby("A.RefreshTime DESC")//获取所选日期最新的
					.queryList();
			if(exchangeRateList!=null && exchangeRateList.size()>0){
				List<TcwWanliExchangeRate> exchangeRateListByGbp = exchangeRateList.stream().filter(item->item.getCurrencyCode().equals("GBP")).collect(Collectors.toList());
				if(exchangeRateListByGbp.size()>0){
					exchangeRateByGbp =  exchangeRateListByGbp.get(0).getExchangeRate();
				}
				List<TcwWanliExchangeRate> exchangeRateListByUsd = exchangeRateList.stream().filter(item->item.getCurrencyCode().equals("USD")).collect(Collectors.toList());
				if(exchangeRateListByUsd.size()>0){
					exchangeRateByUsd =  exchangeRateListByUsd.get(0).getExchangeRate();
				}
				List<TcwWanliExchangeRate> exchangeRateListByEur = exchangeRateList.stream().filter(item->item.getCurrencyCode().equals("EUR")).collect(Collectors.toList());
				if(exchangeRateListByEur.size()>0){
					exchangeRateByEur =  exchangeRateListByEur.get(0).getExchangeRate();
				}
			}
		}

		//填入数据
		entity.setExchangeRateByGbp(exchangeRateByGbp);
		entity.setExchangeRateByUsd(exchangeRateByUsd);
		entity.setExchangeRateByEur(exchangeRateByEur);
		return entity;
	}

	/**
	 * 万里汇预付款入账单主表信息计算
	 */
	@Override
	public TcwWanliPrepaymentRecorded countMsg(TcwWanliPrepaymentRecorded entity) throws Exception{
		BigDecimal exchangeRateByGbp = entity.getExchangeRateByGbp()!=null?entity.getExchangeRateByGbp():BigDecimal.ZERO;//GBP计算汇率
		BigDecimal exchangeRateByUsd = entity.getExchangeRateByUsd()!=null?entity.getExchangeRateByUsd():BigDecimal.ZERO;//USD计算汇率
		BigDecimal exchangeRateByEur = entity.getExchangeRateByEur()!=null?entity.getExchangeRateByEur():BigDecimal.ZERO;//EUR计算汇率

		BigDecimal poolingTotal = BigDecimal.ZERO;//总计归集金额（CNY）
		BigDecimal reconciliationFeeTotal = BigDecimal.ZERO;//对账手续费（CNY）
		BigDecimal countFeeTotal = BigDecimal.ZERO;//计算手续费（CNY）
		BigDecimal recordedTotal = BigDecimal.ZERO;//总入账金额（CNY）
		BigDecimal recordedOperations = BigDecimal.ZERO;//运营入账金额（CNY）
		BigDecimal recordedFinance = BigDecimal.ZERO;//财务入账金额（CNY）
		BigDecimal amountCny = BigDecimal.ZERO;//CNY金额

		BigDecimal amountGuijiGbp = BigDecimal.ZERO;//GBP归集金额
		BigDecimal amountGuijiUsd = BigDecimal.ZERO;//USD归集金额
		BigDecimal amountGuijiEur = BigDecimal.ZERO;//EUR归集金额
		BigDecimal feeGbp = BigDecimal.ZERO;//GBP手续费
		BigDecimal feeUsd = BigDecimal.ZERO;//USD手续费
		BigDecimal feeEur = BigDecimal.ZERO;//EUR手续费

		TcwWanliReconciliation tcwWanliReconciliation = new TcwWanliReconciliation().setBid(entity.getReconciliationBid()).queryFirst();
		if(tcwWanliReconciliation!=null){
			if(checkUtil.isNotNullByObject(tcwWanliReconciliation.getAmountGuijiGbp())) amountGuijiGbp = tcwWanliReconciliation.getAmountGuijiGbp();
			if(checkUtil.isNotNullByObject(tcwWanliReconciliation.getAmountGuijiUsd())) amountGuijiUsd = tcwWanliReconciliation.getAmountGuijiUsd();
			if(checkUtil.isNotNullByObject(tcwWanliReconciliation.getAmountGuijiEur())) amountGuijiEur = tcwWanliReconciliation.getAmountGuijiEur();
			if(checkUtil.isNotNullByObject(tcwWanliReconciliation.getFeeGbp())) feeGbp = tcwWanliReconciliation.getFeeGbp();
			if(checkUtil.isNotNullByObject(tcwWanliReconciliation.getFeeUsd())) feeUsd = tcwWanliReconciliation.getFeeUsd();
			if(checkUtil.isNotNullByObject(tcwWanliReconciliation.getFeeEur())) feeEur = tcwWanliReconciliation.getFeeEur();
			if(checkUtil.isNotNullByObject(tcwWanliReconciliation.getAmountCny())) amountCny = tcwWanliReconciliation.getAmountCny();
		}

		//总计归集金额（CNY） = 币种归集金额*计算汇率之和
		poolingTotal = amountGuijiGbp.multiply(exchangeRateByGbp)
				.add(amountGuijiUsd.multiply(exchangeRateByUsd))
				.add(amountGuijiEur.multiply(exchangeRateByEur))
				.setScale(2, RoundingMode.HALF_UP);//保留2位小数
		//对账手续费（CNY） = 币种手续费金额*计算汇率之和
		reconciliationFeeTotal = feeGbp.multiply(exchangeRateByGbp)
				.add(feeUsd.multiply(exchangeRateByUsd))
				.add(feeEur.multiply(exchangeRateByEur))
				.setScale(2, RoundingMode.HALF_UP);//保留2位小数

		//计算手续费（CNY） = 总计归集金额（CNY）*0.002
		countFeeTotal = poolingTotal.multiply(new BigDecimal(0.002)).setScale(2, RoundingMode.HALF_UP);//保留2位小数
		//总入账金额（CNY） = 总计归集金额（CNY）-对账手续费（CNY）
		recordedTotal = poolingTotal.subtract(reconciliationFeeTotal);
		//运营入账金额（CNY） = 子表入账金额之和
		List<TcwWanliPrepaymentRecordedItem> itemList = new TcwWanliPrepaymentRecordedItem().setPbid(entity.getBid()).queryList();
		if(itemList!=null && itemList.size()>0){
			for(TcwWanliPrepaymentRecordedItem item:itemList){
				if(checkUtil.isNotNullByObject(item.getRecordedAmount())){
					recordedOperations = recordedOperations.add(item.getRecordedAmount());
				}
			}
		}
		//旧：财务入账金额（CNY） = 总入账金额（CNY）-运营入账金额（CNY）
		//新：财务入账金额（CNY） = CNY金额 - 运营入账金额（CNY）
		recordedFinance = amountCny.subtract(recordedOperations);

		//填入数据
		entity.setPoolingTotal(poolingTotal);
		entity.setReconciliationFeeTotal(reconciliationFeeTotal);
		entity.setCountFeeTotal(countFeeTotal);
		entity.setRecordedTotal(recordedTotal);
		entity.setRecordedOperations(recordedOperations);
		entity.setRecordedFinance(recordedFinance);
		entity.setAmountCny(amountCny);
		return entity;
	}


	//保存列表信息
	public R saveItem(Map<String, Object> params,TcwWanliPrepaymentRecorded entity){
		BigDecimal exchangeRateByGbp = entity.getExchangeRateByGbp();//GBP计算汇率
		BigDecimal exchangeRateByUsd = entity.getExchangeRateByUsd();//USD计算汇率
		BigDecimal exchangeRateByEur = entity.getExchangeRateByEur();//EUR计算汇率
		//保存列表信息
		List<Map<String, Object>> paramsNewByItem = new ArrayList<>();
		if(params.get("subData")!=null){
			//验证详情信息
			JSONArray subData = JSON.parseArray(params.get("subData").toString());
			String errorBackByItem = null;//错误信息
			if(subData!=null && subData.size()>0){
				for (int i = 0; i < subData.size(); i++) {
					JSONObject jSONObject = subData.getJSONObject(i);
					Map<String, Object> paramsNewByRecord = new HashMap<>();
					if(checkUtil.isNotNullByObject(jSONObject.get("itemId")))paramsNewByRecord.put("id",jSONObject.get("itemId"));//id
					if(checkUtil.isNotNullByObject(jSONObject.get("reconciliationItemId"))){
						paramsNewByRecord.put("reconciliationItemId",jSONObject.get("reconciliationItemId"));//预付款对账单子表id
					}else {
						errorBackByItem = "第"+(i+1)+"行的调取预付款对账单列表信息为空！";
					}

					//计算：入账金额（CNY） = 记录归集金额*对应币种的计算汇率*0.998*0.98；
					BigDecimal recordAmountGuiji = BigDecimal.ZERO;//记录归集金额
					BigDecimal exchangeRate = BigDecimal.ZERO;//对应币种的计算汇率
					if(checkUtil.isNotNullByObject(jSONObject.get("recordAmountGuiji"))){//获取记录归集金额
						recordAmountGuiji = new BigDecimal(jSONObject.get("recordAmountGuiji").toString());
					}
					//根据币种设置汇率
					if(checkUtil.isNotNullByObject(jSONObject.get("jyCurrencyCode"))){//交易币种
						String jyCurrencyCode = jSONObject.get("jyCurrencyCode").toString();
						if(jyCurrencyCode.equals("GBP")){
							exchangeRate = exchangeRateByGbp;
						}else if(jyCurrencyCode.equals("USD")){
							exchangeRate = exchangeRateByUsd;
						}else if(jyCurrencyCode.equals("EUR")){
							exchangeRate = exchangeRateByEur;
						}
					}
					logger.info("归集金额:"+recordAmountGuiji+"；计算汇率:"+exchangeRate);
					//计算入账金额（CNY） = 记录归集金额*对应币种的计算汇率*0.998*0.98；
					BigDecimal recordedAmount = recordAmountGuiji
							.multiply(exchangeRate)
							.multiply(new BigDecimal(0.998))
							.multiply(new BigDecimal(0.98))
							.setScale(2, RoundingMode.HALF_UP);//保留2位小数

					paramsNewByRecord.put("recordedAmount",recordedAmount);

					paramsNewByItem.add(paramsNewByRecord);
				}
				if(errorBackByItem!=null && !"".equals(errorBackByItem)){
					return R.error(errorBackByItem);
				}
			}else {
				return R.error("列表信息为空！");
			}
		}else {
			return R.error("列表信息为空！");
		}

		//删除列表信息
		financeMapper.deleteWanliPrepaymentRecordedItemByPbid(entity.getBid());
		for (int i = 0; i < paramsNewByItem.size(); i++) {
			Map<String, Object> item = paramsNewByItem.get(i);
			TcwWanliPrepaymentRecordedItem entityItem = JSON.parseObject(JSON.toJSONString(item), TcwWanliPrepaymentRecordedItem.class);
			entityItem.setStatus(1);
			entityItem.setPbid(entity.getBid());
			//新增
			tcwWanliPrepaymentRecordedItemMapper.insert(entityItem);
			/*
			if(entityItem.getId()!=null){
				//修改
				tcwWanliPrepaymentRecordedItemMapper.update(entityItem);
			}else {

			}

			 */
		}
		return R.ok();
	}


	//删除
	@Override
	@Transactional
	public R del(Long id) throws Exception{
		if (id == null) {
			return R.error("ID不能为空");
		}
		TcwWanliPrepaymentRecorded entity = new TcwWanliPrepaymentRecorded().setId(id).queryFirst();
		if (entity.getEffectStock() == FlowEnum.EffectStock.EFFECTED.value) {
			return R.error("已生效数据无法删除");
		}
		// 验证是否制单人
		String loginUserId = ShiroUtils.getUserId();
		TsUserChange tsUserChange = new TsUserChange().setId(entity.getCreateChangeId()).queryFirst();
		if (!tsUserChange.getUserId().equals(loginUserId) && !"admin".equals(loginUserId)) {
			return R.error("非制单人，无法删除");
		}
		//删除
		tcwWanliPrepaymentRecordedMapper.deleteTrue(id);
		//删除列表信息
		financeMapper.deleteWanliPrepaymentRecordedItemByPbid(entity.getBid());
		//删除流程
		yspTaskService.flowDelete(entity.getBid(), loginUserId);
		return R.ok();
	}

	//删除列表
	@Override
	@Transactional
	public R toDelByItem(Long id) throws Exception{
		tcwWanliPrepaymentRecordedItemMapper.deleteTrue(id);
		return R.ok();
	}

	/**
	 * 流转通过
	 */
	@Override
	@Transactional
	public R flowPass(Long id, String loginUserId) throws Exception {

		TcwWanliPrepaymentRecorded entity = new TcwWanliPrepaymentRecorded().setId(id).queryFirst();
		Flow f = yspTaskService.flowPass(entity.getBid(), loginUserId);
		if (f.getCode() == Flow.Code.FAILED.value) {
			return R.error(f.getMsg());
		} else {
			if (f.getState() == Flow.State.FINISH.value) {
				flowFinish(entity.getBid());
			}
			return R.ok();
		}
	}

	/**
	 * 流转结束
	 */
	@Override
	@Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
	public void flowFinish(String bid) throws Exception {

		TcwWanliPrepaymentRecorded entity = new TcwWanliPrepaymentRecorded().setBid(bid).queryFirst();
		YsProcInst ysProcInst = new YsProcInst().setBid(entity.getBid()).queryFirst();
		if (ysProcInst.getStateFlow() != YsProcInstEnum.StateFlow.FINISH.value) {
			return;
		}
		Date theDate = new Date();
		entity.setEffectStock(FlowEnum.EffectStock.EFFECTED.value);
		entity.setUpdateTime(theDate);

		List<TcwWanliPrepaymentRecordedItem> itemList = new TcwWanliPrepaymentRecordedItem().setPbid(entity.getBid()).queryList();
		if(itemList!=null && itemList.size()>0){
			for(TcwWanliPrepaymentRecordedItem sonItem:itemList){
				logger.info("*******进行id="+sonItem.getId()+" 的关联操作*******");
				//获取对账单子表信息
				TcwWanliReconciliationItem tcwWanliReconciliationItem = new TcwWanliReconciliationItem().setId(sonItem.getReconciliationItemId()).queryFirst();
				if(tcwWanliReconciliationItem!=null){
					//预付款归集明细--对应数据标记为已付款
					TcwWanliPrepaymentPooling tcwWanliPrepaymentPooling = new TcwWanliPrepaymentPooling();
					//修改入账状态
					tcwWanliPrepaymentPooling.setRecordedStatus(1);//已入账
					tcwWanliPrepaymentPooling.setId(tcwWanliReconciliationItem.getWanliPrepaymentPoolingId());
					tcwWanliPrepaymentPoolingMapper.update(tcwWanliPrepaymentPooling);

					//管理绩效逻辑产生交易流水
					//入账金额
					BigDecimal recordedAmount = sonItem.getRecordedAmount();
					logger.info("入账金额:"+recordedAmount);

					//明细信息
					Map<String,Object> poolingInfo = new TcwWanliPrepaymentPooling()
							//.addField("D.Vgsbm AS vgsbm")
							.addField("O.Vgsjc AS vgsjc")
							.addField("O.ManageRatio AS manageRatio")
							//.addLeftJoin("TCW_DepositPlatformAccount D ON D.Mid = A.FkMid")
							.addLeftJoin("THR_OperateCompanyApply O ON O.Vgsbm = A.Vgsbm")
							.setId(tcwWanliReconciliationItem.getWanliPrepaymentPoolingId())
							.queryFirstMap();

					String vgsbm = poolingInfo.get("vgsbm").toString();
					String vgsjc = poolingInfo.get("vgsjc").toString();
					BigDecimal manageRatio = BigDecimal.ZERO;//管理比例
					if(checkUtil.isNotNullByObject(poolingInfo.get("manageRatio"))){
						manageRatio = new BigDecimal(poolingInfo.get("manageRatio").toString());
					}

					//运营公司入账流水
					if(recordedAmount.compareTo(BigDecimal.ZERO)!=0){
						tcwAccountDetailedForCompanyService.addTcwAccountDetailedForCompanyWithJcNoTrigger(
								vgsbm,vgsjc,
								"HZZH0002", "AMAZON", TransactionTypeEnum.BusinessType.TCW_WanliPrepaymentRecorded_1.name,
								(recordedAmount.compareTo(BigDecimal.ZERO)<0?recordedAmount.abs():recordedAmount),
								theDate,theDate,
								"WF预付款入账单："+ bid + "，币种："+ poolingInfo.get("jyCurrencyCode") + "，记录归集金额："+ tcwWanliReconciliationItem.getRecordAmountGuiji(),
								bid,theDate);

					}

					//*******15%到运营事业部*******
					BigDecimal recordedAmountCount15 = recordedAmount.multiply(new BigDecimal(0.15)).setScale(2, RoundingMode.HALF_UP);//保留2位小数
					if(recordedAmountCount15.compareTo(BigDecimal.ZERO)<0){
						recordedAmountCount15 = recordedAmountCount15.abs();
					}
					logger.info("15%到运营事业部:"+recordedAmountCount15);
					if(recordedAmountCount15.compareTo(BigDecimal.ZERO)!=0){
						//运营公司管理绩效支出流水（转账，两条数据）
						tcwAccountDetailedForCompanyService.addTcwAccountDetailedForCompanyWithJcNoTrigger(
								vgsbm,vgsjc,
								"GS0002", "运营事业部",TransactionTypeEnum.BusinessType.TCW_WanliPrepaymentRecorded_2.name,
								recordedAmountCount15.negate(),theDate,theDate,
								"管理绩效（15.00%），WF预付款入账单："+ bid + "，入账公司：" + vgsbm + vgsjc,
								bid,theDate);
						tcwAccountDetailedForCompanyService.addTcwAccountDetailedForCompanyWithJcNoTrigger(
								"GS0002", "运营事业部",
								poolingInfo.get("vgsbm").toString(),poolingInfo.get("vgsjc").toString(),
								TransactionTypeEnum.BusinessType.TCW_WanliPrepaymentRecorded_2.name,
								recordedAmountCount15,theDate,theDate,
								"管理绩效（15.00%），WF预付款入账单："+ bid + "，入账公司：" + vgsbm + vgsjc,
								bid,theDate);
					}

					//*******10%进行分配*******
					BigDecimal recordedAmountCount10 = recordedAmount.multiply(new BigDecimal(0.1)).setScale(2, RoundingMode.HALF_UP);//保留2位小数
					if(recordedAmountCount10.compareTo(BigDecimal.ZERO)<0){
						recordedAmountCount10 = recordedAmountCount10.abs();
					}
					logger.info("10%进行分配:"+recordedAmountCount10);
					BigDecimal remaining = BigDecimal.ZERO;//剩余培训费
					BigDecimal trainingFees = BigDecimal.ZERO;//培训费标准
					BigDecimal gfJe = BigDecimal.ZERO;//已收培训费
					BigDecimal gfJeByNew = BigDecimal.ZERO;//新已收培训费
					BigDecimal gfJeByAdd = BigDecimal.ZERO;//收到的培训费
					//获取对应运营公司的，培训费信息
					ThrOperateCompanyApply thrOperateCompanyApply = new ThrOperateCompanyApply().setVgsbm(vgsbm).queryFirst();
					if(thrOperateCompanyApply!=null){
						if(checkUtil.isNotNullByObject(thrOperateCompanyApply.getTrainingFees()))trainingFees = thrOperateCompanyApply.getTrainingFees();
						if(checkUtil.isNotNullByObject(thrOperateCompanyApply.getGfJe()))gfJe = thrOperateCompanyApply.getGfJe();
					}
					logger.info("培训费标准:"+trainingFees+"，已收培训费:"+gfJe);
					BigDecimal deductTrainingFees = (trainingFees.subtract(gfJe)).compareTo(BigDecimal.ZERO)<0?BigDecimal.ZERO:trainingFees.subtract(gfJe);//可加的培训费数
					if(deductTrainingFees.compareTo(recordedAmountCount10)>=0 && deductTrainingFees.compareTo(BigDecimal.ZERO)!=0){//全部扣到培训费
						gfJeByNew = gfJe.add(recordedAmountCount10);
						gfJeByAdd = recordedAmountCount10;//收到的培训费 = 分配金额
					}else {//全部扣完培训费还有剩余
						remaining = recordedAmountCount10.subtract(deductTrainingFees);
						gfJeByNew = trainingFees;
						gfJeByAdd = deductTrainingFees;//收到的培训费 = 可加的培训费数
					}
					if(thrOperateCompanyApply!=null){
						thrOperateCompanyApply.setGfJe(gfJeByNew);
						thrOperateCompanyApplyMapper.update(thrOperateCompanyApply);//修改已收培训费
					}
					logger.info("剩余培训费:"+remaining+"，新已收培训费:"+gfJeByNew+"，收到的培训费:"+gfJeByAdd);
					if(gfJeByAdd.compareTo(BigDecimal.ZERO)<=0){
						logger.info("公司:"+vgsbm+"，收到的培训费计算出来小于0");
					}
					if(gfJeByAdd.compareTo(BigDecimal.ZERO)!=0 && gfJeByAdd.compareTo(BigDecimal.ZERO)>0){
						//培训费流水
						tcwAccountDetailedForCompanyService.addTcwAccountDetailedForCompanyWithJcNoTrigger(
								"GS0002","运营事业部","GS0856", "运营支持中心",
								TransactionTypeEnum.BusinessType.TCW_WanliPrepaymentRecorded_3.name,gfJeByAdd.negate(),theDate,theDate,
								"WF预付款入账单："+ bid + "，入账公司：" + vgsbm + vgsjc,
								bid,theDate);
						tcwAccountDetailedForCompanyService.addTcwAccountDetailedForCompanyWithJcNoTrigger(
								"GS0856", "运营支持中心","GS0002","运营事业部",
								TransactionTypeEnum.BusinessType.TCW_WanliPrepaymentRecorded_3.name,gfJeByAdd,theDate,theDate,
								"WF预付款入账单："+ bid + "，入账公司：" + vgsbm + vgsjc,
								bid,theDate);
					}

					//*******管理绩效分配*******
					//如果还有剩余
					if(remaining.compareTo(BigDecimal.ZERO)>0){
						//hrMapper Map<String, Object> getParentCompanyInfo
						BigDecimal baseRatio = new BigDecimal(10);//基础比例是10%
						BigDecimal firstSubtractRatio = new BigDecimal(85);//第一个分配的公司管理比例减85%

						BigDecimal firstRatio = BigDecimal.ZERO;//第一家的最终比例
						BigDecimal secondRatio = BigDecimal.ZERO;//第二家的最终比例
						BigDecimal thirdRatio = BigDecimal.ZERO;//第三家的最终比例

						BigDecimal firstRatioCount = manageRatio.subtract(firstSubtractRatio);//第一家的比例差额
						BigDecimal secondRatioCount = BigDecimal.ZERO;
						BigDecimal thirdRatioCount = BigDecimal.ZERO;

						if(firstRatioCount.compareTo(baseRatio)>=0){//第一家的比例计算大于10%
							firstRatio = baseRatio;
							baseRatio = BigDecimal.ZERO;//剩余比例0
						}else{
							firstRatio = (firstRatioCount.compareTo(BigDecimal.ZERO)<0?BigDecimal.ZERO:firstRatioCount);
							baseRatio = baseRatio.subtract((firstRatioCount.compareTo(BigDecimal.ZERO)<0?BigDecimal.ZERO:firstRatioCount));//剩余比例 = 10% - 第一家的比例计算
						}
						logger.info("第一个分配的公司:"+vgsjc+"；管理比例:"+manageRatio+"；剩余比例："+baseRatio+"；最终比例:"+firstRatio);

						String vgsbmSecond = "";
						String vgsjcSecond = "";
						String vgsbmThird = "";
						String vgsjcThird = "";
						if(baseRatio.compareTo(BigDecimal.ZERO)>0){
							//上级计算***计算开始
							//获取上级公司编码
							Map<String, Object> getParentCompanyInfoSecond = hrMapper.getParentCompanyInfo(vgsbm);
							if(getParentCompanyInfoSecond!=null){
								vgsbmSecond = getParentCompanyInfoSecond.get("vgsbm").toString();
								vgsjcSecond = getParentCompanyInfoSecond.get("vgsjc").toString();
								if(vgsbmSecond.equals(vgsbm)){
									Map<String, Object> getParentCompanyInfoSecondByNew = hrMapper.getParentParentCompanyInfo(vgsbm);
									vgsbmSecond = getParentCompanyInfoSecondByNew.get("vgsbm").toString();
									vgsjcSecond = getParentCompanyInfoSecondByNew.get("vgsjc").toString();
								}

								ThrOperateCompanyApply companyApplySecond = new ThrOperateCompanyApply().setVgsbm(vgsbmSecond).queryFirst();
								if(companyApplySecond!=null){
									BigDecimal manageRatioSecond = BigDecimal.ZERO;//管理比例
									if(checkUtil.isNotNullByObject(companyApplySecond.getManageRatio())){
										manageRatioSecond = companyApplySecond.getManageRatio();
									}
									secondRatioCount = manageRatioSecond.subtract(manageRatio);//第二家的比例计算
									if(secondRatioCount.compareTo(baseRatio)>=0){//第二家的比例计算大于剩余比例
										secondRatio = baseRatio;
										baseRatio = BigDecimal.ZERO;//剩余比例0
									}else{
										secondRatio = (secondRatioCount.compareTo(BigDecimal.ZERO)<0?BigDecimal.ZERO:secondRatioCount);
										baseRatio = baseRatio.subtract((secondRatioCount.compareTo(BigDecimal.ZERO)<0?BigDecimal.ZERO:secondRatioCount));//剩余比例 = 剩余比例 - 第二家的比例计算
									}
									logger.info("第二个分配的公司:"+vgsjcSecond+"；管理比例:"+manageRatioSecond+"；剩余比例："+baseRatio+"；最终比例:"+secondRatio);
									//上上级***计算开始
									if(baseRatio.compareTo(BigDecimal.ZERO)>0){
										//上上级计算
										//获取上级公司编码
										Map<String, Object> getParentCompanyInfoThird = hrMapper.getParentCompanyInfo(vgsbmSecond);
										if(getParentCompanyInfoThird!=null){
											vgsbmThird = getParentCompanyInfoThird.get("vgsbm").toString();
											vgsjcThird = getParentCompanyInfoThird.get("vgsjc").toString();
											if(vgsbmThird.equals(vgsbmSecond)){
												Map<String, Object> getParentCompanyInfoThirdByNew = hrMapper.getParentParentCompanyInfo(vgsbmSecond);
												vgsbmThird = getParentCompanyInfoThirdByNew.get("vgsbm").toString();
												vgsjcThird = getParentCompanyInfoThirdByNew.get("vgsjc").toString();
											}

											ThrOperateCompanyApply companyApplyThird = new ThrOperateCompanyApply().setVgsbm(vgsbmThird).queryFirst();
											if(companyApplyThird!=null){
												BigDecimal manageRatioThird = BigDecimal.ZERO;//管理比例
												if(checkUtil.isNotNullByObject(companyApplyThird.getManageRatio())){
													manageRatioThird = companyApplyThird.getManageRatio();
												}
												thirdRatioCount = manageRatioThird.subtract(manageRatioSecond);//第三家的比例计算
												if(thirdRatioCount.compareTo(baseRatio)>=0){//第三家的比例计算大于剩余比例
													thirdRatio = baseRatio;
													//baseRatio = BigDecimal.ZERO;//剩余比例0
												}else{
													thirdRatio = (thirdRatioCount.compareTo(BigDecimal.ZERO)<0?BigDecimal.ZERO:thirdRatioCount);
													//baseRatio = baseRatio.subtract(secondThirdCount);//剩余比例 = 剩余比例 - 第三家的比例计算
												}
												logger.info("第三个分配的公司:"+vgsjcThird+"；管理比例:"+manageRatioThird+"；最终比例:"+thirdRatio);
											}

										}
									}
									//上上级***计算结束
								}
							}
						}
						//上级***计算结束
						logger.info("第一家的最终比例:"+firstRatio+"，第二家的最终比例:"+secondRatio+"，第三家的最终比例:"+thirdRatio);
						//根据各家比例计算分配的金额
						BigDecimal firstAmount = BigDecimal.ZERO;
						BigDecimal secondAmount = BigDecimal.ZERO;
						BigDecimal thirdAmount = BigDecimal.ZERO;
						if(firstRatio.compareTo(BigDecimal.ZERO)>0){
							firstAmount = recordedAmount.multiply(firstRatio).divide(new BigDecimal(100),2,BigDecimal.ROUND_HALF_UP);//保留2位小数，四舍五入
						}
						if(secondRatio.compareTo(BigDecimal.ZERO)>0){
							secondAmount = recordedAmount.multiply(secondRatio).divide(new BigDecimal(100),2,BigDecimal.ROUND_HALF_UP);//保留2位小数，四舍五入
						}
						if(thirdRatio.compareTo(BigDecimal.ZERO)>0){
							thirdAmount = recordedAmount.multiply(thirdRatio).divide(new BigDecimal(100),2,BigDecimal.ROUND_HALF_UP);//保留2位小数，四舍五入
						}
						logger.info("第一家计算:"+firstAmount+"，第二家计算:"+secondAmount+"，第三家计算:"+thirdAmount);
						//新增流水
						if(firstAmount.compareTo(BigDecimal.ZERO)>0){
							tcwAccountDetailedForCompanyService.addTcwAccountDetailedForCompanyWithJcNoTrigger(
									"GS0002","运营事业部",vgsbm, vgsjc,
									TransactionTypeEnum.BusinessType.TCW_WanliPrepaymentRecorded_4.name,
									firstAmount.negate(),theDate,theDate,
									"管理绩效（"+firstRatioCount+"），WF预付款入账单："+ bid + "，入账公司：" + vgsbm + vgsjc,
									bid,theDate);

							tcwAccountDetailedForCompanyService.addTcwAccountDetailedForCompanyWithJcNoTrigger(
									vgsbm, vgsjc,"GS0002","运营事业部",
									TransactionTypeEnum.BusinessType.TCW_WanliPrepaymentRecorded_4.name,
									firstAmount,theDate,theDate,
									"管理绩效（"+firstRatioCount+"），WF预付款入账单："+ bid + "，入账公司：" + vgsbm + vgsjc,
									bid,theDate);
						}
						if(secondAmount.compareTo(BigDecimal.ZERO)>0){
							tcwAccountDetailedForCompanyService.addTcwAccountDetailedForCompanyWithJcNoTrigger(
									"GS0002","运营事业部",vgsbmSecond, vgsjcSecond,
									TransactionTypeEnum.BusinessType.TCW_WanliPrepaymentRecorded_4.name,
									secondAmount.negate(),theDate,theDate,
									"管理绩效（"+secondRatioCount+"），WF预付款入账单："+ bid + "，入账公司：" + vgsbm + vgsjc,
									bid,theDate);

							tcwAccountDetailedForCompanyService.addTcwAccountDetailedForCompanyWithJcNoTrigger(
									vgsbmSecond, vgsjcSecond,"GS0002","运营事业部",
									TransactionTypeEnum.BusinessType.TCW_WanliPrepaymentRecorded_4.name,
									secondAmount,theDate,theDate,
									"管理绩效（"+secondRatioCount+"），WF预付款入账单："+ bid + "，入账公司：" + vgsbm + vgsjc,
									bid,theDate);
						}
						if(thirdAmount.compareTo(BigDecimal.ZERO)>0){
							tcwAccountDetailedForCompanyService.addTcwAccountDetailedForCompanyWithJcNoTrigger(
									"GS0002","运营事业部", vgsbmThird, vgsjcThird,
									TransactionTypeEnum.BusinessType.TCW_WanliPrepaymentRecorded_4.name,
									thirdAmount.negate(),theDate,theDate,
									"管理绩效（"+thirdRatioCount+"），WF预付款入账单："+ bid + "，入账公司：" + vgsbm + vgsjc,
									bid,theDate);

							tcwAccountDetailedForCompanyService.addTcwAccountDetailedForCompanyWithJcNoTrigger(
									vgsbmThird, vgsjcThird,"GS0002","运营事业部",
									TransactionTypeEnum.BusinessType.TCW_WanliPrepaymentRecorded_4.name,
									thirdAmount,theDate,theDate,
									"管理绩效（"+thirdRatioCount+"），WF预付款入账单："+ bid + "，入账公司：" + vgsbm + vgsjc,
									bid,theDate);
						}

					}

					//新增：运营公司预付款管理
					R res = tcwOperateCompanyPrepaymentService.addOrAccrualWanliInfo(vgsbm,entity.getDepositPlatformCode(),sonItem.getRecordedAmount(),
							BigDecimal.ZERO,BigDecimal.ZERO,BigDecimal.ZERO ,
							ShiroUtils.getUserId(),
							TcwOperateCompanyPrepaymentFlowEnum.FromType.TCW_WanliPrepaymentRecorded.value,
							entity.getBid(),entity.getBid());
					if(res.getCode().equals( R.Code.FAILED.value)){
						throw new IllegalArgumentException(res.getMsg());
					}
				}
			}
		}else{
			throw new IllegalArgumentException("未查询到对应的子表数据");
		}

		//按目标生成流水明细
		if(entity.getRecordedFinance().compareTo(BigDecimal.ZERO)!=0){
			tcwAccountDetailedForCompanyService.addTcwAccountDetailedForCompanyWithJcNoTrigger(
					"GS0889","问前集团",
					"HZZH0002", "AMAZON","经营费用→手续费",
					entity.getRecordedFinance(),theDate,theDate,
					"WF预付款入账单：单号："+ bid,
					bid,theDate);
		}


		//修改信息
		tcwWanliPrepaymentRecordedMapper.update(entity);
	}

	//删除
	@Override
	@Transactional
	public R toDelItemByBid(String bid) throws Exception{
		//删除列表信息
		financeMapper.deleteWanliPrepaymentRecordedItemByPbid(bid);
		return R.ok();
	}

	/**
	 * 参数验证
	 */
	public String checkParams(Map<String, Object> params, Long menuId) throws Exception {
		//获取pc字段数据
		List<YsCol> listField = new YsCol()
				.where("A.MenuId = "+menuId)
				.setOrderby("A.SortNo ASC")
				.queryList();
		//验证必填字段的非空；其他字段的长度限制、类型
		String backMsg = checkUtil.checkTableColLengthAndDataType("TCW_WanliPrepaymentRecorded",listField,params,ysColItem->ysColItem.getFormEditRequired()!=null && ysColItem.getFormEditRequired() == 1);
		return backMsg;
	}




	//获取列表数据
	@Override
	@Transactional
	public Map<String,Object> getExtraParam( String bid) throws Exception{
		Map<String,Object> entity = new TcwWanliPrepaymentRecorded()

				.addLeftJoin("YS_ProcInst P ON P.Bid = A.Bid ")
				.addField("FORMAT(P.UpdateTime, 'yyyy-MM-dd hh:mm:ss') AS auditingTime")//审核时间

				.addLeftJoin("TCW_DepositPlatform D ON D.Code = A.DepositPlatformCode ")//万里汇账号资金
				.addField("D.PlatformName AS platformName")//收款平台名称
				.addField("D.Code AS depositPlatformCode")//账号编码
				.addField("D.Name AS name")//账号名称
				.addField("D.Mid AS depositPlatformMid")//Mid

				.addLeftJoin("TB_CompanyInfo O ON O.Vid = D.CompanyVid ")//公司信息表
				.addField("O.Vname AS vname")//公司名称

				.addLeftJoin("TCW_WanliReconciliation R ON R.Bid = A.ReconciliationBid ")//万里汇预付款对账单
				.addField("R.ReconciliationDayBegin AS reconciliationDayBegin")//对账日期
				.addField("R.ReconciliationDayEnd AS reconciliationDayEnd")//对账日期
				.addField("R.AmountGuijiGbp AS amountGuijiGbp")//GBP归集金额
				.addField("R.AmountGuijiUsd AS amountGuijiUsd")//USD归集金额
				.addField("R.AmountGuijiEur AS amountGuijiEur")//EUR归集金额
				.addField("R.FeeGbp AS feeGbp")//GBP手续费
				.addField("R.FeeUsd AS feeUsd")//USD手续费
				.addField("R.FeeEur AS feeEur")//EUR手续费

				.setBid(bid)
				.queryFirstMap();

		Map<String, Object> extraParam = entity;
		//关联数据
		if(entity.get("auditingTime")!=null)extraParam.put("auditingTime", entity.get("auditingTime"));
		if(entity.get("platformName")!=null)extraParam.put("platformName", entity.get("platformName"));
		if(entity.get("depositPlatformCode")!=null)extraParam.put("depositPlatformCode", entity.get("depositPlatformCode"));
		if(entity.get("depositPlatformMid")!=null)extraParam.put("depositPlatformMid", entity.get("depositPlatformMid"));
		if(entity.get("name")!=null)extraParam.put("name", entity.get("name"));
		if(entity.get("vname")!=null)extraParam.put("vname", entity.get("vname"));

		if(entity.get("reconciliationDayBegin")!=null)extraParam.put("reconciliationDayBegin", entity.get("reconciliationDayBegin"));
		if(entity.get("reconciliationDayEnd")!=null)extraParam.put("reconciliationDayEnd", entity.get("reconciliationDayEnd"));
		if(entity.get("amountGuijiGbp")!=null)extraParam.put("amountGuijiGbp", entity.get("amountGuijiGbp"));
		if(entity.get("amountGuijiUsd")!=null)extraParam.put("amountGuijiUsd", entity.get("amountGuijiUsd"));
		if(entity.get("amountGuijiEur")!=null)extraParam.put("amountGuijiEur", entity.get("amountGuijiEur"));
		if(entity.get("feeGbp")!=null)extraParam.put("feeGbp", entity.get("feeGbp"));
		if(entity.get("feeUsd")!=null)extraParam.put("feeUsd", entity.get("feeUsd"));
		if(entity.get("feeEur")!=null)extraParam.put("feeEur", entity.get("feeEur"));
		return extraParam;
	}
	//获取子列表数据
	@Override
	@Transactional
	public List<Map<String, Object>> getItemList( String bid) throws Exception{
		List<Map<String, Object>> itemList = new TcwWanliPrepaymentRecordedItem()
				.addField("A.Id AS itemId")//id

				.addLeftJoin("TCW_WanliReconciliationItem I ON I.Id = A.ReconciliationItemId ")//对账表
				.addField("I.RecordAmountGuiji AS recordAmountGuiji")//记录归集金额

				.addLeftJoin("TCW_WanliPrepaymentPooling P ON P.Id = I.WanliPrepaymentPoolingId ")//收款平台账号管理

				.addField("P.FkMid AS fkMid")//付款人MID
				.addField("P.PayerAccountNo AS payerAccountNo")//付款人账号
				.addField("P.PayerName AS fkVyhzhmc")//付款人名称
				.addField("P.fkVyhsx AS fkVyhsx")//付款方账号类型
				.addField("P.Vgsbm AS fkVgsbm")//运营公司编码

				.addLeftJoin("THR_OperateCompanyApply C1 ON C1.Vgsbm = P.Vgsbm ")
				.addField("C1.Vgsjc AS fkVgsjc")//运营公司简称

				.addField("P.SkMid AS skMid")//收款人MID
				.addField("P.BeneficiaryAccountNo AS beneficiaryAccountNo")//收款账号

				.addField("P.BeneficiaryName AS skVyhzhmc")//收款人名称
				.addField("P.skVyhsx AS skVyhsx")//收款方账号类型

				.addField("P.TransactionType AS transactionType")//动账类型
				.addField("P.OriginalTransactionAmount AS originalTransactionAmount")//交易金额
				.addField("P.JyCurrencyCode AS jyCurrencyCode")//交易币种
				.addField("P.ExtTransactionId AS extTransactionId")//商户订单号
				.addField("P.TransactionId AS transactionId")//交易号
				.addField("P.TransactionTime AS transactionTime")//交易创建时间
				.addField("P.TransactionStatus AS transactionStatus")//交易状态
				.addField("P.ReconciliationStatus AS reconciliationStatus")//是否对账


				.setPbid(bid)
				.queryMap();
		return itemList;
	}



}
